#ifndef V2_NIM_LOGIN_SERVICE_H
#define V2_NIM_LOGIN_SERVICE_H
#include "v2_nim_internal.hpp"
namespace v2 {
/// @brief 登录服务
/// @pre
/// 调用 `V2NIMClient::get()` 拿到 client 实例
/// 调用 `client.getLoginService()` 拿到 loginService 实例
/// @par 示例代码
/// @code
/// auto& client = V2NIMClient::get();
/// auto& loginService = client.getLoginService();
/// @endcode
class V2NIMLoginService {
public:
    /// @brief 登录接口
    /// @param accountId 账号
    /// @param token 密码
    /// @param option 登录选项
    /// @param success 成功回调
    /// @param failure 失败回调
    /// @return void
    /// @par 示例代码
    /// @code
    /// V2NIMLoginOption option;
    /// loginService.login(
    ///     "accountId",
    ///     "token",
    ///     option,
    ///     []() {
    ///         // login succeeded
    ///     },
    ///     [](V2NIMError error) {
    ///         // login failed, handle error
    ///     });
    /// @endcode
    virtual void login(nstd::string accountId,
        nstd::string token,
        V2NIMLoginOption option,
        V2NIMSuccessCallback<void> success,
        V2NIMFailureCallback failure) = 0;

    /// @brief 登出接口
    /// @param success 成功回调
    /// @param failure 失败回调
    /// @return void
    /// @par 示例代码
    /// @code
    /// loginService.logout(
    ///     []() {
    ///         // logout succeeded
    ///     },
    ///     [](V2NIMError error) {
    ///         // logout failed, handle error
    ///     });
    /// @endcode
    virtual void logout(V2NIMSuccessCallback<void> success, V2NIMFailureCallback failure) = 0;

    /// @brief 获取当前登录用户
    /// @return nstd::string 当前登录用户
    /// @par 示例代码
    /// @code
    /// auto loginUser = loginService.getLoginUser();
    /// @endcode
    virtual nstd::string getLoginUser() = 0;

    /// @brief 获取登录状态
    /// @return V2NIMLoginStatus 登录状态
    /// @par 示例代码
    /// @code
    /// auto loginStatus = loginService.getLoginStatus();
    /// @endcode
    virtual V2NIMLoginStatus getLoginStatus() = 0;

    /// @brief 获取登录客户端列表
    /// @return nstd::vector<V2NIMLoginClient> 登录客户端列表
    /// @par 示例代码
    /// @code
    /// auto loginClients = loginService.getLoginClients();
    /// @endcode
    virtual nstd::vector<V2NIMLoginClient> getLoginClients() = 0;

    /// @brief 踢掉登录客户端下线
    /// @param client 登录客户端
    /// @param success 成功回调
    /// @param failure 失败回调
    /// @return void
    /// @par 示例代码
    /// @code
    /// // get `client` from `getLoginClients()` or other place
    /// loginService.kickOffline(
    ///     client,
    ///     []() {
    ///         // kick client succeeded
    ///     },
    ///     [](V2NIMError error) {
    ///         // kick client failed, handle error
    ///     });
    /// @endcode
    virtual void kickOffline(V2NIMLoginClient client, V2NIMSuccessCallback<void> success, V2NIMFailureCallback failure) = 0;

    /// @brief 获取被踢下线原因
    /// @return V2NIMKickedOfflineDetail 被踢下线原因
    /// @par 示例代码
    /// @code
    /// auto kickedOfflineDetail = loginService.getKickedOfflineDetail();
    /// @endcode
    virtual nstd::optional<V2NIMKickedOfflineDetail> getKickedOfflineDetail() = 0;

    /// @brief 获取连接状态
    /// @return V2NIMConnectStatus 连接状态
    /// @par 示例代码
    /// @code
    /// auto connectStatus = loginService.getConnectStatus();
    /// @endcode
    virtual V2NIMConnectStatus getConnectStatus() = 0;

    /// @brief 获取数据同步状态
    /// @return nstd::vector<V2NIMDataSyncDetail> 数据同步状态列表
    /// @par 示例代码
    /// @code
    /// auto dataSyncDetails = loginService.getDataSync();
    /// @endcode
    virtual nstd::vector<V2NIMDataSyncDetail> getDataSync() = 0;

    /// @brief 获取聊天室 link 地址
    /// @param roomId 聊天室 ID
    /// @return void
    /// @par 示例代码
    /// @code
    /// loginService.getChatroomLinkAddress(
    ///     "roomId",
    ///     [](nstd::vector<nstd::string> linkAddresses) {
    ///         // handle link addresses
    ///     },
    ///     [](V2NIMError error) {
    ///         // handle error
    ///     });
    /// @endcode
    virtual void getChatroomLinkAddress(nstd::string roomId,
        V2NIMSuccessCallback<nstd::vector<nstd::string>> success,
        V2NIMFailureCallback failure) = 0;

    /// @brief 设置获取重连延时回调
    /// @param provider 获取重连延时回调
    /// @return void
    /// @par 示例代码
    /// @code
    /// loginService.setReconnectDelayProvider([](uint32_t defaultDelay) {
    ///     uint32_t delay = defaultDelay;
    ///     // do something to calculate delay
    ///     // ...
    ///     return delay;
    /// });
    /// @endcode
    virtual void setReconnectDelayProvider(V2NIMReconnectDelayProvider provider) = 0;

    /// @brief 注册登录监听器
    /// @param listener 登录监听器
    /// @return void
    /// @par 示例代码
    /// @code
    /// V2NIMLoginListener listener;
    /// listener.onLoginStatus = [](V2NIMLoginStatus status) {
    ///     // handle login status
    /// };
    /// listener.onLoginFailed = [](V2NIMError error) {
    ///     // handle login error
    /// };
    /// listener.onKickedOffline = [](V2NIMKickedOfflineDetail detail) {
    ///     // handle kicked offline detail
    /// };
    /// listener.onLoginClientChanged = [](V2NIMLoginClientChange change, nstd::vector<V2NIMLoginClient> clients) {
    ///     // handle login client change
    /// };
    /// loginService.addLoginListener(listener);
    /// @endcode
    virtual void addLoginListener(V2NIMLoginListener listener) = 0;

    /// @brief 移除登录监听器
    /// @return void
    /// @par 示例代码
    /// @code
    /// V2NIMLoginListener listener;
    /// // ......
    /// loginService.addLoginListener(listener);
    /// // ......
    /// loginService.removeLoginListener(listener);
    /// @endcode
    virtual void removeLoginListener(V2NIMLoginListener listener) = 0;

    /// @brief 添加登录详情监听
    /// @param listener 登录详情监听
    /// @return void
    /// @par 示例代码
    /// @code
    /// V2NIMLoginDetailListener listener;
    /// listener.onConnectStatus = [](V2NIMConnectStatus status) {
    ///     // handle connect status change event
    /// };
    /// listener.onDisconnected = [](V2NIMError error) {
    ///     // handle disconnected error
    /// };
    /// listener.onConnectFailed = [](V2NIMError error) {
    ///     // handle connect failed error
    /// };
    /// listener.onDataSync = [](V2NIMDataSync dataSync, bool begin, V2NIMError error) {
    ///     // handle data sync event
    /// };
    /// loginService.addLoginDetailListener(listener);
    /// @endcode
    virtual void addLoginDetailListener(V2NIMLoginDetailListener listener) = 0;

    /// @brief 移除登录详情监听
    /// @return void
    /// @par 示例代码
    /// @code
    /// V2NIMLoginDetailListener listener;
    /// // ......
    /// loginService.addLoginDetailListener(listener);
    /// // ......
    /// loginService.removeLoginDetailListener(listener);
    /// @endcode
    virtual void removeLoginDetailListener(V2NIMLoginDetailListener listener) = 0;
};
}  // namespace v2

#endif